<script setup lang="ts">
import { onMounted, provide, ref, watchEffect } from "vue";
import markerHeader from "@/assets/green-wave/marker_header@2x.png";
import markerClose from "@/assets/dashboard/marker_close.png";
import markerLightImg from "@/assets/dashboard/icon_light@2x.png";
import { wgs84tobd09 } from "@/utils/map";
import Left from "./components/Left.vue";
import Timeline from "./components/timeline2/index.vue";
import { HIGH, LOW, MEDIUM } from "./constants";
import Popup from "./components/Popup.vue";
import { SYMBOL_INDEX_PROVIDER } from "./constants";
import { useCityRoadStore } from "@/store/city-road";
import { storeToRefs } from "pinia";
import { DATE_FORMAT } from "@/const";
import { mapIndexShow, webConfig } from "@/services/city-road";
import Indicator from "./components/Indicator.vue";
const toFixed = (num: number) => {
    return Number(num).toFixed(2);
};

const map = ref<any>(null);
const mapConfig = ref<any>({
    centerPoint: [],
    zoom: 14,
});
const createMap = () => {
    const map = new BMapGL.Map("container");
    const centerPoint: any[] = mapConfig.value.centerPoint?.length
        ? mapConfig.value.centerPoint
        : wgs84tobd09(120.05762, 32.227029);
    const zoom = mapConfig.value.zoom || 14;
    const point = new BMapGL.Point(...centerPoint);
    map.centerAndZoom(point, zoom);
    map.enableScrollWheelZoom(true);
    map.setMapStyleV2({
        styleId: "4e4376721b62bd7c018312fde9e2efaa",
    });
    return map;
};

// const trafficFn = () => {
//     traffic.value = !traffic.value;

// };

// const traffic = ref<boolean>(true);
// const zoominFn = () => {
//     if (map.value) {
//         map.value.zoomIn();
//     }
// };

// const zoomoutFn = () => {
//     if (map.value) {
//         map.value.zoomOut();
//     }
// };

const createLable = ({
    point = [116.404, 39.915],
    offset = [0, 0],
    text,
    mapInstance,
}: any) => {
    const opts = {
        position: new BMapGL.Point(...point), // 指定文本标注所在的地理位置
        offset: new BMapGL.Size(...offset), // 设置文本偏移量
    };
    // 创建文本标注对象
    const label = new BMapGL.Label(text, opts);
    // 自定义文本标注样式

    label.setStyle({
        color: "#C0D9F2",
        borderRadius: "4px",
        borderColor: "#5286CE",
        backgroundColor: "rgba(8,27,53,0.85)",
        padding: "6px",
        fontSize: "14px",
        height: "30px",
        lineHeight: "14px",
        fontFamily: "微软雅黑",
    });
    mapInstance?.addOverlay?.(label);
    return label;
};
const marker = ref<any>(null);
const markerVisible = ref<boolean>(false);
const pixel = ref<any>({ x: 0, y: 0 });
const compOverlay = ref<any>(null);
const markerRecord = ref<any>({});

const compOverlayClose = () => {
    markerVisible.value = false;
    map.value.removeOverlay(compOverlay.value);
};
const createDOM = ({ point, record }: any) => {
    // 创建自定义覆盖物
    function ComplexCustomOverlay() {}
    ComplexCustomOverlay.prototype = new BMapGL.Overlay();
    ComplexCustomOverlay.prototype.initialize = function () {
        markerRecord.value = record;
        this._div = marker.value;
        this._div.onmouseover = function () {};
        this._div.onmouseout = function () {};
        map.value.getPanes().labelPane.appendChild(this._div);
        return this._div;
    };
    ComplexCustomOverlay.prototype.draw = function () {
        pixel.value = map.value.pointToOverlayPixel(point);
    };
    markerVisible.value = true;
    const myCompOverlay: any = new (ComplexCustomOverlay as any)();
    map.value?.addOverlay?.(myCompOverlay);
    compOverlay.value = myCompOverlay;
    return myCompOverlay;
};

const points = ref<any>([]);
const getLevel = (lowSpeedRatio: number) => {
    if (lowSpeedRatio < 20) {
        return LOW;
    } else if (lowSpeedRatio >= 20 && lowSpeedRatio <= 30) {
        return MEDIUM;
    } else {
        return HIGH;
    }
};
const createIcon = ({ point = [], mapInstance, record }: any) => {
    const markerLightIcon = new BMapGL.Icon(
        markerLightImg,
        new BMapGL.Size(10, 30)
    );
    markerLightIcon.setImageSize(new BMapGL.Size(8, 24));
    const pt = new BMapGL.Point(...point);

    const markerLight = new BMapGL.Marker(pt, {
        icon: markerLightIcon,
    });
    markerLight.setZIndex(1000);
    markerLight.addEventListener("mouseover", function () {
        if (markerLight.label) {
            markerLight.label.show();
        } else {
            markerLight.label = createLable({
                point,
                text: record.name,
                offset: [10, -30],
                mapInstance: map.value,
            });
        }
    });
    markerLight.addEventListener("mouseout", function () {
        markerLight.label.hide();
    });
    markerLight.addEventListener("click", function () {
        map.value.centerAndZoom(pt, 18);
        // createDOM({
        //     point: pt,
        //     record,
        // });
    });
    points.value.push(markerLight);
    mapInstance?.addOverlay?.(markerLight);
};

const cross = ref<any[]>([]);
const roadseg = ref<any[]>([]);
const getMapIndexShow = async (params: any) => {
    const data: any = await mapIndexShow({
        ...params,
    });
    cross.value = data.cross || [];
    cross.value.forEach((item) => {
        createIcon({
            point: item.location,
            mapInstance: map.value,
            record: item,
        });
    });
    roadseg.value = data.roadseg || [];
    createLine(roadseg.value);
};
const initMap: any = async () => {
    mapConfig.value = await webConfig();
    map.value = createMap();
};
// const clearTime = ref<any>(null);
const polylineList = ref<any>([]);
const setPolyLine = (width = 4) => {
    polylineList.value.forEach((item: any) => {
        item.polyline.setStrokeWeight(width);
    });
};

const getZoomMap = () => {
    const zoom: number = map.value.getZoom();

    if (zoom < 8) {
        setPolyLine(1);
        markerVisible.value = false;
    } else if (zoom >= 8 && zoom < 13) {
        setPolyLine(2);
        markerVisible.value = false;
    } else if (zoom >= 13 && zoom < 17) {
        setPolyLine(3);
        markerVisible.value = false;
    } else if (zoom >= 17) {
        setPolyLine(4);
    }
    if (zoom >= 15) {
        points.value.forEach((item: any) => {
            item.show();
        });
    } else {
        points.value.forEach((item: any) => {
            item.hide();
        });
    }
};
// const hiddenMarkerVisible = () => {
//     if (clearTime.value) {
//         clearTimeout(clearTime.value);
//     }
//     clearTime.value = setTimeout(() => {
//         markerVisible.value = false;
//     }, 1000);
// };

// const showMarkerVisible = () => {
//     if (clearTime.value) {
//         clearTimeout(clearTime.value);
//     }

//     markerVisible.value = true;
// };
const store = useCityRoadStore();
const lineMap: any = {};
const createLine = async (lineStringIndexListData: any[]) => {
    lineStringIndexListData.forEach((item: any) => {
        let strokeColor = "rgba(255, 77, 77, 1)";
        // let borderColor = "rgba(255, 77, 77, .3)";
        const level = getLevel(item.decreaseRate);
        if (level === LOW) {
            strokeColor = "rgba(255, 77, 77, 1)";
            // borderColor = "rgba(255, 77, 77, .3)";
        } else if (level === MEDIUM) {
            strokeColor = "rgba(246, 189, 22, 1)";
            // borderColor = "rgba(246, 189, 22, .3)";
        } else if (level === HIGH) {
            strokeColor = "rgba(90, 216, 166, 1)";
            // borderColor = "rgba(90, 216, 166,  .3)";
        }
        const polyline = new BMapGL.Polyline(
            item.location.map((p: any) => new BMapGL.Point(...p)),
            {
                strokeColor,
                strokeWeight: 4,
            }
        );
        lineMap[item.roadId] = {
            layer: polyline,
            record: item,
        };

        map.value?.addOverlay?.(polyline);
        polyline.addEventListener("mouseover", function (e: any) {
            polyline.setStrokeWeight(8);
            createDOM({
                point: e.latLng,
                record: item,
            });
        });
        polyline.addEventListener("mouseout", function () {
            polyline.setStrokeWeight(4);
            // hiddenMarkerVisible();
        });
        polyline.addEventListener("click", function (e: any) {
            map.value.centerAndZoom(e.latLng, 20);
            store.updateRoad({
                id: item.roadId,
                name: item.roadName,
                roadsegId: item.roadsegId,
                roadsegName: item.roadsegName,
            });
        });
        polylineList.value.push({
            polyline,
            record: {
                id: item.roadId,
                name: item.roadName,
                roadsegId: item.roadsegId,
                roadsegName: item.roadsegName,
            },
        });
    });
};
const { weekRange, startTime, endTime, dateType } = storeToRefs(store);

onMounted(async () => {
    initMap();
    const [start, end] = weekRange.value;
    await getMapIndexShow({
        beginTime: start?.format(DATE_FORMAT) + " " + startTime.value + ":00",
        endTime: end?.format(DATE_FORMAT) + " " + endTime.value + ":00",
        dateType: dateType.value,
    });
    getZoomMap();
    map.value.addEventListener("zoomend", function () {
        // 获取缩放级别
        getZoomMap();
    });
});

// watchEffect(() => {
//     polylineList.value.forEach((item: any) => {
//         item.polyline.setStrokeOpacity(0);
//         if (
//             currentRoad.value &&
//             Array.from(currentRoad.value).includes(item.record.id)
//         ) {
//             console.log(item.polyline.setVisible);
//             item.polyline.setStrokeOpacity(1);
//             // map.value.removeOverlay(item.polyline);
//         } else {
//             // item.polyline.setStrokeOpacity(1);
//             // map.value.addOverlay(item.polyline);
//         }
//     });
// });
watchEffect(async () => {
    if (weekRange.value?.length !== 2) {
        return;
    }
    const [start, end] = weekRange.value;

    try {
        await getMapIndexShow({
            beginTime:
                start?.format(DATE_FORMAT) + " " + startTime.value + ":00",
            endTime: end?.format(DATE_FORMAT) + " " + endTime.value + ":00",
            dateType: dateType.value,
        });
    } catch (error) {}
});

function driveMap({ id }: any) {
    const item = lineMap[id] || {};
    const { record = {} } = item;
    if (record.location) {
        const point = new BMapGL.Point(...record.location[0]);
        map.value.centerAndZoom(point, 14);
        createDOM({
            point,
            record: item.record,
        });
    }
}
function updateRoad(checkedRoads: any) {
    polylineList.value.forEach((item: any) => {
        console.log(checkedRoads);

        if (checkedRoads && checkedRoads?.includes?.(item.record.id)) {
            // item.polyline.setStrokeOpacity(1);
            // map.value.removeOverlay(item.polyline);
            map.value.addOverlay(item.polyline);
            console.log(item.polyline);
        } else {
            map.value.removeOverlay(item.polyline);
            // map.value.addOverlay(item.polyline);
        }
    });
}

provide(SYMBOL_INDEX_PROVIDER, {
    driveMap,
    updateRoad,
});

const trafficFn = () => {
    traffic.value = !traffic.value;
    if (map.value) {
        getZoomMap();
    }
};

const traffic = ref<boolean>(true);
const zoominFn = () => {
    if (map.value) {
        map.value.zoomIn();
    }
};

const zoomoutFn = () => {
    if (map.value) {
        map.value.zoomOut();
    }
};
</script>

<template>
    <div id="container"></div>
    <div>
        <!-- @mouseover="showMarkerVisible"
            @mouseout="hiddenMarkerVisible" -->
        <div
            ref="marker"
            class="marker"
            v-show="markerVisible"
            :style="{ left: pixel.x + 26 + 'px', top: pixel.y - 16 + 'px' }"
        >
            <img
                :src="markerClose"
                alt=""
                class="marker_close"
                @click="compOverlayClose"
            />
            <div class="marker_header">
                <div class="marker_header_roadName">
                    <img :src="markerHeader" alt="" />
                    {{ markerRecord.roadName }}
                </div>
                <div class="marker_header_name">
                    {{ markerRecord.roadsegName }}
                </div>
            </div>
            <div class="marker_container">
                <div class="marker_container_item">
                    <div class="marker_container_item_title">通过率</div>
                    <div class="marker_container_item_desc marker_stop">
                        {{ toFixed(100 - markerRecord.decreaseRate) }}%
                    </div>
                </div>
                <div class="marker_container_item">
                    <div class="marker_container_item_title">实际车速</div>
                    <div class="marker_container_item_desc">
                        {{ markerRecord.roadsegSpeed }}km/h
                    </div>
                </div>
            </div>
        </div>
    </div>

    <Left @zoomin="zoomoutFn" @zoomout="zoominFn" @traffic="trafficFn" />
    <Popup />
    <div class="timeline"><Timeline /></div>
    <Indicator />
</template>
<style lang="scss" scoped>
#container {
    height: 100vh;
}

.marker {
    position: absolute;
    background: url(@/assets/dashboard/marker_bg@2x.png) no-repeat center center /
        100% 100%;
    padding: 12px 14px 18px;
    width: 238px;
    // height: 160px;
    box-sizing: border-box;
    .marker_close {
        position: absolute;
        width: 28px;
        height: 28px;
        top: -14px;
        right: -14px;
        cursor: pointer;
    }
    .marker_header {
        .marker_header_roadName {
            display: flex;
            align-items: center;
            font-weight: 600;
            font-size: 16px;
            color: #ffffff;
            line-height: 22px;
            text-align: left;
            img {
                width: 30px;
            }
        }
        .marker_header_name {
            font-weight: 400;
            font-size: 16px;
            color: #4bc6ff;
            line-height: 22px;
        }
    }
    .marker_container {
        margin-top: 10px;
        border: 1px solid #346694;
        .marker_container_item {
            display: flex;
            border-bottom: 1px solid #346694;
            &:last-of-type {
                border: none;
            }
            .marker_container_item_title {
                text-align: center;
                background: #113067;
                width: 84px;
                height: 34px;
                line-height: 34px;
                color: #c0d9f2;
                border-right: 1px solid #346694;
            }
            .marker_container_item_desc {
                padding-left: 14px;
                font-weight: 400;
                font-size: 14px;
                line-height: 34px;
                color: #c0d9f2;
                background: #041b40;
                flex: 1;
                &.marker_stop {
                    color: rgba(117, 248, 131, 1);
                }
            }
        }
    }
}
.timeline {
    position: fixed;
    top: 50%;
    transform: translate(-50%, -50%);
    right: 10px;
    z-index: 9999;
    cursor: pointer;
}
</style>
